import base64
import json
import os
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../')))
import backend.DID.Communication_Management as Communication_Management
from Cryptodome.Cipher import AES
from Cryptodome.Hash import SHA256
from Cryptodome.Protocol.KDF import PBKDF2
from Cryptodome.Random import get_random_bytes
import  backend.DID.Key_Management as Key_Management
import rsa
import backend.DID.Identity_Management as Identity_Management 
import  backend.DID.BlockChain as BlockChain
import backend.DID.DataBase as DataBase
def encrypt_by_sharekey(sharekey,meg):     # 接收bytes类型的明文
    try:
        # print(f"meg:{meg}")
        cipher = AES.new(sharekey, AES.MODE_EAX)
        nonce = cipher.nonce
        ciphertext, tag = cipher.encrypt_and_digest(meg)
       
        # print(f"base64.b64encode(nonce + tag + ciphertext):{base64.b64encode(nonce + tag + ciphertext)}")
        return base64.b64encode(nonce + tag + ciphertext)
                 

    except Exception as e:
        print(f"DID: 加解密管理共享密钥加密数据失败，错误：{e}")
        return False

def decrypt_by_sharekey(sharekey,encrypt_meg):
    try:
        encrypt_meg=base64.b64decode(encrypt_meg)
        nonce=encrypt_meg[:16]
        tag=encrypt_meg[16:32]
        ciphertext=encrypt_meg[32:]
        cipher = AES.new(sharekey, AES.MODE_EAX, nonce=nonce)


        meg = cipher.decrypt_and_verify(ciphertext, tag)
        return meg
    except Exception as e:
        print(f"DID: 加解密管理共享密钥解密数据失败，错误：{e}")
        return False


def encrypt_by_publickey(meg,publickey):   # 传入bytes
    try:
        chunk_size = 117  # RSA-1024 最大明文长度
        chunks = [meg[i:i + chunk_size] for i in range(0, len(meg), chunk_size)]
        encrypted_chunks = []

        for chunk in chunks:
            encrypted_chunk = rsa.encrypt(chunk, publickey)
            encrypted_chunks.append(encrypted_chunk)

        return b''.join(encrypted_chunks)

        # encrypt_meg=rsa.encrypt(meg,publickey)
        # return encrypt_meg                       # 传出bytes
    except Exception as e:
        print(f"DID: 加解密管理公钥加密数据失败，错误：{e}")
        return False

def decrypt_by_privatekey(encrypt_meg,privatekey):    # 传入bytes
    try:
        chunk_size = 128  # RSA-1024 固定密文长度
        chunks = [encrypt_meg[i:i + chunk_size] for i in range(0, len(encrypt_meg), chunk_size)]
        decrypted_chunks = []

        for chunk in chunks:
            decrypted_chunk = rsa.decrypt(chunk, privatekey)
            decrypted_chunks.append(decrypted_chunk)

        return b''.join(decrypted_chunks)  # 合并还原数据

        # decrypt_meg=rsa.decrypt(encrypt_meg,privatekey)
        # return decrypt_meg                    # 传出bytes
    except Exception as e:
        print(f"DID: 加解密管理私钥解密数据失败，错误：{e}")
        return False

def package(sender_DID, receiver_DID, sharekey_encrypt_by_publickey_s,sharekey_encrypt_by_publickey_r,encrypt_meg):
    try:
        file={
            sender_DID:sharekey_encrypt_by_publickey_s,
            receiver_DID:sharekey_encrypt_by_publickey_r,
            "encrypt_meg":encrypt_meg
        }
        return file
    except Exception as e:
        print(f"DID: 加解密管理打包数据失败，错误：{e}")
        return False

def find_id(device_id,cpu_id,Disc_id):
    try:
        hard_disk_number=(
            device_id,
            cpu_id,
            Disc_id
        )
        hash=Identity_Management.hashFunction(hard_disk_number)
        hash1={
            'hash1':f'{hash}'
        }
        table = 'blockchain'
        id=BlockChain.query_data(table,hash1,'id')
        return id

    except Exception as e:
        print(f"DID: 加解密管理找设备主人id失败，错误：{e}")
        return False

def encrypt_privatekey(privatekey,password):
    try:
        privatekey_bytes=privatekey.encode('utf-8')
        salt=get_random_bytes(16)
        nonce=get_random_bytes(16)
        key = PBKDF2(
            password=password.encode('utf-8'),
            salt=salt,
            dkLen=32,
            count=100000,
            hmac_hash_module=SHA256
        )

        cipher=AES.new(key,AES.MODE_GCM,nonce=nonce)
        ciphertext,tag=cipher.encrypt_and_digest(privatekey_bytes)
        encrypted_data = salt + nonce + tag + ciphertext
        encrypt_privatekey=base64.b64encode(encrypted_data).decode('utf-8')
        return encrypt_privatekey
    except Exception as e:
        print(f"DID: 加解密管理加密私钥失败，错误：{e}")
        return False

def decrypt_privatekey(encrypt_privatekey,password):
    try:
        encrypt_bytes=base64.b64decode(encrypt_privatekey.encode('utf-8'))
        salt = encrypt_bytes[:16]
        nonce = encrypt_bytes[16:32]
        tag = encrypt_bytes[32:48]
        ciphertext = encrypt_bytes[48:]

        key = PBKDF2(
            password=password.encode('utf-8'),
            salt=salt,
            dkLen=32,
            count=100000,
            hmac_hash_module=SHA256
        )
        cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
        private_key_bytes = cipher.decrypt_and_verify(ciphertext, tag)
        privatekey=private_key_bytes.decode('utf-8')
        return privatekey
    except Exception as e:
        print(f"DID: 加解密管理解密私钥失败，错误：{e}")
        return False

def encrypt_package(sender_DID, receiver_DID, data):
    try:
        # print(f"data1:{data}")
        share_key=Key_Management.generate_aes_key()
        encrypt_data=encrypt_by_sharekey(share_key,data)   # 使用密钥加密数据
        # print(f"encrypt2:{encrypt_data}")
        publickey_s = Communication_Management.search_publickey(sender_DID)  # 找sender的publickey
        # print(f"p1:{publickey_s}")

        publickey_r =BlockChain.query_temporary_PublicKey(sender_DID,receiver_DID)   # 找receiver的临时publickey
        # print(f"p2:{publickey_r}")

        sharekey_encrypt_by_publickey_s=encrypt_by_publickey(share_key,publickey_s)
        sharekey_encrypt_by_publickey_r=encrypt_by_publickey(share_key,publickey_r)
        # 临时公私钥加密！
        file=package(sender_DID, receiver_DID, sharekey_encrypt_by_publickey_s,sharekey_encrypt_by_publickey_r,encrypt_data)
        # print(f"ff:{file}")
        return file
    except Exception as e:
        print(f"DID: 加解密管理encrypt_package失败，错误：{e}")
        return False

def decrypt_package(encrypt_file):
    try:
        did=DataBase.search_did()
        sender_did=None
        sharekey=encrypt_file[did]
        all_keys = encrypt_file.keys()

        for key in all_keys:
            if key != did and key != "encrypt_meg":
                sender_did = key
                break

        the_path = 'temporary_key_other_to_me.db'
        privatekey=DataBase.search_data(the_path,'temporary_key_other_to_me','other_id',sender_did,'temporary_PrivateKey')
        private_key=rsa.PrivateKey.load_pkcs1(privatekey.encode('utf-8'))
        sharekey_decrypt=decrypt_by_privatekey(sharekey,private_key)

        encrypt_data=encrypt_file["encrypt_meg"]
        decrypt_file=json.loads(decrypt_by_sharekey(sharekey_decrypt,encrypt_data))
        return decrypt_file
    except Exception as e:
        print(f"DID: 加解密管理decrypt_package失败，错误：{e}")
        return False

def create_group(groupID,member_id):
    try:
        groupkey=Key_Management.generate_aes_key()
        owner_id=member_id[0]
        table='group_owner'
        data={
            'ownerId':owner_id,
            'groupId':groupID
        }
        BlockChain.insert_into_blockchain(table,data)  # 群主与群对应关系上传至区块链


        for x in member_id:
            table_db='blockchain'
            value={
                'id':f'{x}'
            }
            publickey_f=BlockChain.query_data(table_db,value,'publickey').encode('utf-8')
            publickey=rsa.PublicKey.load_pkcs1(publickey_f)
            encrypt_groupkey=base64.b64encode(encrypt_by_publickey(groupkey,publickey)).decode('utf-8')

            table_name='group_key'
            data_id={
                'groupId':groupID,
                'memberId':x,
                'encryptGroupKey':encrypt_groupkey
            }
            BlockChain.insert_into_blockchain(table_name,data_id)

        print("群密钥上传成功！")
        return True
    except Exception as e:
        print(f"DID: 加解密管理create_group失败，错误：{e}")
        return False

def get_groupkey(groupID,DID):
    try:
        # print(f"[DID] get_groupkey:{groupkey} groupID: {groupID}, DID: {DID
        # print('区块链私钥：',BlockChain.query_group_key(groupID,DID))
        groupkey=base64.b64decode(BlockChain.query_group_key(groupID,DID).encode('utf-8'))

        print(f"groupkey2:{groupkey}")


        privatekey=DataBase.private_key_changes(DID)
        groupkey_decrypt = decrypt_by_privatekey(groupkey, privatekey)
        return groupkey_decrypt
    except Exception as e:
        print(f"DID: 加解密管理get_groupkey失败，错误：{e}")
        return False
